﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Core.Utility.Helper
{
    /// <summary>
    /// 对象助手类
    /// </summary>
    public static class ObjectHelper
    {
        /// <summary>
        /// 合并差异
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">差异的源对象</param>
        /// <param name="target">差异的目标对象</param>
        /// <returns>以源对象为基础，返回合并后的结果</returns>
        public static T MergeDiff<T>(this T source,T target) where T:new()
        {
            if(source == null || target == null)
            {
                return source;
            }
            T res = source.DeepCopyByReflectionT();
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if (property.CanRead && property.CanWrite)
                {
                    object? sourceValue = property.GetValue(source);
                    object? targetValue = property.GetValue(target);
                    if (!Equals(sourceValue, targetValue))
                    {
                        property.SetValue(res, targetValue);
                    }
                }
            }
            return res;
        }

        /// <summary>
        /// 合并差异
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">差异的源对象</param>
        /// <param name="value1">差异比较对象1</param>
        /// <param name="value2">差异比较对象2，</param>
        /// <returns>以源对象为基础，返回合并后的结果</returns>
        public static T MergeDiff<T>(this T source, T value1,T value2) where T : new()
        {
            if (source == null || value1 == null || value2 == null)
            {
                return source;
            }
            T res = source.DeepCopyByReflectionT();
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if (property.CanRead && property.CanWrite)
                {
                    object? sourceValue = property.GetValue(source);
                    object? targetValue1 = property.GetValue(value1);
                    object? targetValue2 = property.GetValue(value2);
                    if (!Equals(sourceValue, targetValue1))
                    {
                        sourceValue = targetValue1;
                        property.SetValue(res, targetValue1);
                    }
                    if (!Equals(sourceValue, targetValue2))
                    {                        
                        property.SetValue(res, targetValue2);
                    }
                }
            }
            return res;
        }
    }
}
